package com.lingxu.base.system.manage.controller;

import com.lingxu.base.common.api.vo.Result;
import com.lingxu.base.common.constant.CacheConstant;
import com.lingxu.base.common.constant.CommonConstant;
import com.lingxu.base.common.shiro.vo.DefConstants;
import com.lingxu.base.common.util.JwtUtil;
import com.lingxu.base.common.util.RedisUtil;
import com.lingxu.base.common.util.encrypt.MD5Utils;
import com.lingxu.base.config.MySessionListener;
import com.lingxu.base.system.api.ISysBaseAPI;
import com.lingxu.base.system.common.service.ISysLogService;
import com.lingxu.base.system.manage.entity.SysUser;
import com.lingxu.base.system.manage.model.SysLoginModel;
import com.lingxu.base.system.manage.service.ILoginService;
import com.lingxu.base.system.manage.vo.LoginUser;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

@RestController
@RequestMapping("/sys")
@Api(tags = "用户登录接口")
@Slf4j
public class LoginController {

    @Resource
    private RedisUtil redisUtil;
    @Resource
    private ISysBaseAPI sysBaseAPI;
    @Resource
    private ILoginService loginService;
    @Resource
    private ISysLogService sysLogService;


    @ApiOperation("账户密码登录")
    @PostMapping(value = "/loginByNamePwd")
    public Result<?> loginByNamePwd(@RequestBody SysLoginModel sysLoginModel,HttpServletRequest request) {
        Result<LoginUser> result;
        //用户信息
        String username = sysLoginModel.getUsername();
       String password = sysLoginModel.getPassword();
        //1.验证用户是否有效
        SysUser sysUser = loginService.getUserByName(username,"1");
        if(sysUser == null){
            return Result.error("该用户不存在！");
        }
        //登录 验证第一层  看用户是否被限制登录
        Map<String, Object> map = loginService.loginUserLock(sysUser);
        //如果为true表示被限制登录
        if ((Boolean) map.get("flag")) {
            sysBaseAPI.addLog("用户名: " + sysLoginModel.getUsername() + ",登录失败！超过了限制登录次数,已被禁止登录！",1, null,sysUser);
            return Result.error("登录失败,因用户名或密码错误超过了限制登录次数,已被禁止登录.还剩" + map.get("lockTime") + "分钟");
        }
        result=loginService.checkStatus(sysUser);
        if(!result.isSuccess()){
            return result;
        }
        //2.校验密码
        result=loginService.checkPWDCorrect(username,password,sysUser);
        if(!result.isSuccess()){
           return result;
       }
        //3.获取登陆信息
        result=Result.ok(loginService.getLoginInfo(sysUser,""),"登录成功");
        //4.日志记录
        sysBaseAPI.addLog("用户名: " + sysLoginModel.getUsername() + ",登录成功！", 1, null,sysUser);
        SecurityUtils.getSubject().getSession().setTimeout(60 * 10 * 1000);
        HttpSession httpSession = request.getSession(true);
        httpSession.setAttribute(username, username);
        AtomicInteger userCount = MySessionListener.userCount;
        log.info("登录成功，当前在线人数：" + userCount);

        return result;
    }

    @RequestMapping(value = "/loginFxxt")
    public Result loginFxxt(String username){
        SysUser   sysUser = loginService.getUserByName(username,"1");
        if(sysUser == null){
            return Result.error("该用户不存在！");
        }
        //3.获取登陆信息
        return Result.ok(loginService.getLoginInfo(sysUser,""),"登录成功");
    }


    @ApiOperation("登出")
    @PostMapping(value = "/logout")
    public Result<?> logout(HttpServletRequest request, HttpServletResponse response){
        String token=request.getHeader(DefConstants.X_ACCESS_TOKEN);
        if(StringUtils.isBlank(token)) {
            return Result.error("退出登录失败！");
        }
        String username = JwtUtil.getUsername(token);
        LoginUser sysUser = sysBaseAPI.getUserByName(username);
        SysUser user = new SysUser();
        if(sysUser!=null) {
            user.setUsername(sysUser.getUsername());
            user.setId(sysUser.getId());
            sysBaseAPI.addLog("用户名: "+sysUser.getName()+",退出成功！", 1, null,user);
            log.info(" 用户名:  "+sysUser.getName()+",退出成功！ ");
            //清空用户登录Token缓存
            redisUtil.del(CommonConstant.PREFIX_USER_TOKEN + token);
            //清空用户登录Shiro权限缓存
            redisUtil.del(CommonConstant.PREFIX_USER_SHIRO_CACHE + sysUser.getId());
            //清空用户的缓存信息（包括部门信息），例如sys:cache:user::<username>
            redisUtil.del(String.format("%s::%s", CacheConstant.SYS_USERS_CACHE, sysUser.getName()));

            //清除session
            HttpSession httpSession = request.getSession(true);
            httpSession.removeAttribute(username);
            httpSession.invalidate();

            //调用shiro的logout
            SecurityUtils.getSubject().logout();
            return Result.ok("退出登录成功！");
        }else {
            return Result.error("Token无效!");
        }
    }
}
